This package aims at modeling time-dose-response cytotoxicity data and retrieve target concentrations at different setting for dose and time. td2pLL means time-dose-two-parameter-log-logistic model.
The td2pLL model is defined as
\[ f(t, d) = 100-100\frac{d^h}{ED_{50}(t)^h + d^h} \]
with
\[ ED_{50} =\Delta \cdot t^{-\gamma} + C_0 . \]
For cytotoxicity data, dose is likely a concentrations and time is likely an exposure duration.
# install.packages("devtools")
# devtools::install_github("jcduda/td2pLL")
library(td2pLL)The data set cytotox is stored in the td2pLL package and is the experimental data of Gu et al. (2018)[ doi].
library(td2pLL)
library(dplyr)
#> Warning: Paket 'dplyr' wurde unter R Version 4.1.3 erstellt
#>
#> Attache Paket: 'dplyr'
#> Die folgenden Objekte sind maskiert von 'package:stats':
#>
#> filter, lag
#> Die folgenden Objekte sind maskiert von 'package:base':
#>
#> intersect, setdiff, setequal, union
data(cytotox)
# Use subset of compound ASP
data_subset <- cytotox[cytotox$compound == "ASP", c("expo", "dose", "resp")]
colnames(data_subset)[1] <- "time"
fit <- fit_td2pLL(data = data_subset)
# In your Viewer in R Studio, you will see this when uncommenting the following line
# plot(fit)video_readme_1
Use summary() to get information on the model fit.
summary(fit)
#>
#> Formula: resp_m ~ 100 - 100 * (dose^h)/((delta * time^(-gamma) + c0)^h +
#> dose^h)
#>
#> Parameters:
#> Estimate Std. Error t value Pr(>|t|)
#> h 2.8878 0.7206 4.007 0.00130 **
#> delta 5.9221 1.9319 3.065 0.00839 **
#> gamma 1.7714 1.5939 1.111 0.28513
#> c0 4.7963 1.3508 3.551 0.00320 **
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 35.86 on 14 degrees of freedom
#>
#> Number of iterations to convergence: 11
#> Achieved convergence tolerance: 1.49e-08Change scale of dose axis to linear scale, so that dose=0 can be displayed:
# Uncommenting the above line will show you the following in the Viewer or R Studio
# plot(fit, xaxis_scale = "linear")readme_video_2
get_ED50s(coefs = coef(fit), times = c(1, 2, 3))
#> time ED50
#> 1 1 10.718380
#> 2 2 6.531001
#> 3 3 5.642143If you are not sure if you need to model time-dependency, you can use the two-step anova-based pipeline using TDR().
In an initial step, via nested anova it is checked if the time has an influence. Specifically, a 2pLL model with upper and lower limit set to 100 and 0, respectively, that ignores the epxosure time component is the null model. The full model is a 2pLL model where for each exposure time, a different \(ED_{50}\) parameter is fitted. Only the \(h\) parameter is shared across exposure times.
If the anova test between these nested models is significant, an effect of the exposure time is assumed to be true. In thas case, a td2pLL model is fitted in the second step, the modeling step. If the pre-test does not yield a significant result, then the regualr 2pLL model with upper and lower limit 100 and 0, respectively, is fitted.
For the data of the above chosen compound, ASP, an influence of the exposure time on the viability was detected.
TDR_res <- TDR(data = data_subset)
TDR_res
#> $pretest
#> $pretest$signif
#> [1] TRUE
#>
#> $pretest$alpha
#> [1] 0.05
#>
#> $pretest$anova
#> ANOVA table
#>
#> ModelDf RSS Df F value p value
#> 1st model 248 86851
#> 2nd model 246 72544 2 24.258 0.000
#>
#> $pretest$conv
#> [1] TRUE
#>
#>
#> $fit
#> Nonlinear regression model
#> model: resp_m ~ 100 - 100 * (dose^h)/((delta * time^(-gamma) + c0)^h + dose^h)
#> data: data_w
#> h delta gamma c0
#> 2.888 5.922 1.771 4.796
#> weighted residual sum-of-squares: 18004
#>
#> Number of iterations to convergence: 11
#> Achieved convergence tolerance: 1.49e-08
# Uncomment to see in Viewer
#plot(TDR_res$fit)If we instead look at the measurements for the BOS compound and reduce the data set a bit to a more realistic size, the pre-test suggests to not model the time-dependency. Therefore, only a one-dimensionl 2pLL model is fitted.
Note that if the data set is large enough, the anova pre-test will always propose to model the time-effect as it will always find a significant (but possibly irrelevant) difference in \(ED_{50}\) values between exposure periods.
This significance-vs-relevance problem is always present in classical frequentist statistical hypothesis testing.
data_subset <- cytotox[cytotox$compound == "BOS" &
cytotox$dose %in% c(0, 0.1, 0.316, 1),
c("expo", "dose", "resp")]
data_subset <- data_subset %>% group_by(expo, dose) %>%
dplyr::filter(dplyr::row_number() <= 3)
colnames(data_subset)[1] <- "time"
TDR_res <- TDR(data = data_subset)
TDR_res$pretest
#> $signif
#> [1] FALSE
#>
#> $alpha
#> [1] 0.05
#>
#> $anova
#> ANOVA table
#>
#> ModelDf RSS Df F value p value
#> 1st model 31 5098.4
#> 2nd model 29 4555.7 2 1.7273 0.1955
#>
#> $conv
#> [1] TRUEplot(TDR_res$fit, type = "all")When only a 2pLL model is fitted, the function drc::drm() is used. In the drc R-package, the \(b\) parameter is thesteepness parameter and the \(e\) parameter is \(\log(EC_{50})\).
summary(TDR_res$fit)
#>
#> Model fitted: Log-logistic (log(ED50) as parameter) with lower limit at 0 and upper limit at 100 (2 parms)
#>
#> Parameter estimates:
#>
#> Estimate Std. Error t-value p-value
#> b:(Intercept) 0.58828 0.13317 4.4174 0.0001131 ***
#> e:(Intercept) -1.45172 0.19075 -7.6107 1.398e-08 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error:
#>
#> 12.82443 (31 degrees of freedom)